package com.briup.day02;

/**
 * 操作符测试类
 */
public class Operator {
    /*
    java中的操作符主要存在以下分类：
        1、赋值操作符，如 = 、+=、-=、*=、/=、%=
        2、算术运算符，如 +、-、*、/、%
        3、比较运算符，如 ==、> 、< 、 >= 、<=
        4、自运算符，如 ++、--；自运算符只能用于变量进行运算
        5、位运算符，就是对数值二进制位进行运算的操作符，如 &、|、^、~
        6、逻辑运算符，对于两个boolean类型、结果为boolean类型值的条件进行运算的操作符，
            如：&、|、!、&&、||
        7、移位运算符：将数值的2进制内容指定向左/右移动指定位数，如 <<、>>、<<<、>>>
        8、三目运算符：根据一个boolean类型的判断条件，在后续提供的两个结果中进行二选一的运算符，
           结构为： condition?result1:result2，如果前面的condition条件结果为true，那么返回result1，
           否则执行返回result2；
           三目运算符可以使用在任何需要返回结果，并且2选1的情况
     */
    // 除了赋值操作外，其余所有的操作都必须在方法中定义和执行
    public static void main(String[] args) {
        int age = 17;
        System.out.println(age >= 18 ? "成年人" : "未成年人");
    }

    private static void test5() {
        // 0000 0001  << 2  0000 0100 4
        int a = 1;
        // << 左移，最终的结果为 原值乘以 2^移动位数 1*2^2 = 4
        System.out.println(a << 2);
        // >> 有符号右移，如果被右移的数值是正数，那么在最高位空缺的地方补0，如果是负数，那么补1
        System.out.println(-1 >> 2);
        // >>> 无符号右移，无论被右移的数值是正数还是负数，那么最高位空缺都补0
        System.out.println(-1 >>> 2);
    }

    private static void test4() {
        int a = 100;
        int c = 101;
        // a++ == c-- ==> 100 == 101 ==> false  a=101，c=100
        // ++a == c++ ==> 102 == 100 ==> false  a=102，c=101
         /*
         &&: 短路与，当多个条件的结果进行&&运算时，如果前面表达式的值为false，
             那么最终的结果必然是false，即后续的条件结果无论是否为true
             都无法改变最终的结果，所以后面的条件不执行
         */
        System.out.println(a++ == c-- && ++a == c++);
        System.out.println("a的结果为:" + a + ",c的结果为:" + c);
        /*
            ||：短路或，当多个条件进行或运算时，如果第一个表达式的结果为true，
            那么后续的条件无论是否为false都无法改变最终结果必然为true的事实，
            所以后面的条件不执行
         */
        System.out.println(true || a-- == ++c);
        System.out.println("a的结果为:" + a + ",c的结果为:" + c);
    }

    private static void test3() {
        // 位运算符：对数值二进制位进行运算的操作符
        // 0110 0100
        byte a = 100;
        // 0000 0011
        byte b = 3;
        // 变量a和变量b进行 与运算，将两个变量的二进制位一一进行运算
        // 同一位中的内容都为1，那么该位结果为1；否则为0
        /*
            0110 0100
          & 0000 0100
          -------------
            0000 0100  = 4
         */
        System.out.println(a & ++b);

        // | 或运算符：将两个变量的二进制位一一进行运算，只要有一者为1，那么结果就为1；
        // 否则，为0
        /*
            0110 0100
          | 0000 0011
          -------------
            0110 0111  = 103
         */
        System.out.println(a | --b);

        // ^ 异或运算符：两个二进制为之间比较，不同为1，相同为0
        /*
            0110 0100
          ^ 0000 0100
          -------------
            0110 0000  = 96
         */
        System.out.println(a ^ ++b);

        // ~ 取反运算符，将数值中所有的二进制位都进行取反操作，包括符号位
        /*
         在计算机底层中，将二进制码分为了原码（10进制直接转为2进制的结果）、
         反码（原码取反，其中符号位不变）、补码（在反码的基础上，进行+1）
         在所有的操作中，都是使用补码进行运算的；其中正数的原码、反码、补码都一样
        */
        // 126 = 0111 1110
        byte c = 126;
        // 取反得到的是该数值的补码 1000 0001
        // 1000 0001 ===> 1000 0000(反码) ===> 1111 1111 原码 -127
        System.out.println(~c);
    }

    private static void test2() {
        int a = 100;
        // a++ 会先获取变量空间内的值100，然后在进行自增运算
        // --a 会对变量a进行自减运算，然后在获取运算后的结果
        int b = a++ + --a;
        System.out.println(b);
    }

    private static void test() {
        // 定义一个变量a，然后将数值 10 赋值给变量a（将10存入a指向的空间）
        int a = 10;
        // 获取变量a空间中的值，给其+100，然后将计算后的结果放回到变量a指向的空间中
        a += 100;
        // 对变量a空间中存储的数据值 110 求余
        int b = a % 3;
        System.out.println("b的结果为：" + b);

        // 比较运算符得出的结果 是 一个 boolean 类型的值
        boolean b1 = a == b;
        System.out.println(b1);

        // 自运算符不能用在常量上，自运算符表示的是对变量进行自增1或自减1的操作
        // a++ 等同于 a+=1，即先从变量a空间中拿到数值，对其+1，然后将结果放回到a空间中
        // 自运算符的执行顺序：自运算符在变量前，是先对变量执行+1操作，然后在使用变量执行其余操作；否则，反之
        int c = ++a; // a=111，c=110
        //
        System.out.println("变量c的值为:" + c);
        System.out.println(a == c);
    }
}
